/* eslint-disable */
import Layers from "../layers";
import TreeBuilder from "./tree-builder";

class Shoot {

    /**
     * 构建 TreeBuilder 对象
     *
     * @return {TreeBuilder}
     */
    static builder() {
        return new TreeBuilder();
    }

    /**
     * 取集合中的字段拼接成字符串
     *
     * @param list  {[]}         集合
     * @param field  {string}    字段名
     * @return {[]}              至少是一个空的数组
     */
    static getListFields(list, field) {
        let res = [];
        if (Layers.isNotEmpty(list)) {
            list.forEach(ele => res.push(ele[field]));
        }
        return res;
    };

    /**
     * 获取 id 串
     *
     * @param list {[]}          集合
     * @return {[]}              至少是一个空的数组
     */
    static getIds(list) {
        return Shoot.getListFields(list, 'id');
    };

    /**
     * 获取 name 串
     *
     * @param list {[]}          集合
     * @return {[]}              至少是一个空的数组
     */
    static getNames(list) {
        return Shoot.getListFields(list, 'name');
    };

    /**
     * 获取 label 串
     *
     * @param list {[]}          集合
     * @return {[]}              至少是一个空的数组
     */
    static getLabels(list) {
        return Shoot.getListFields(list, 'label');
    };


    /**
     * 遍历所有的节点
     *
     * @param tree {[TreeNode]}         树
     * @param children {String}         子级列表字段名
     * @param call {function}           函数回调
     * @return {undefined|boolean}      回调函数可以通过返回 false，提前终止
     */
    static forEach(tree, children, call) {
        if (Layers.isNotEmpty(tree)) {
            let node;
            for (let i = 0; i < tree.length; i++) {
                node = tree[i];
                if (call(node) === false) {
                    return false;
                }
                if (node[children] !== undefined) {
                    if (Shoot.forEach(node[children], call) === false) {
                        return false;
                    }
                }
            }
        }
    }

    /**
     * 取出满足条件的第一个元素
     *
     * @param tree {[TreeNode]}         树
     * @param children {String}         子级列表字段名
     * @param filter {function}         返回 true 的时候，取出该元素
     * @return {TreeNode}             至少是一个空的数组
     */
    static fetch(tree, children, filter) {
        if (Layers.isNotEmpty(tree)) {
            let ret = undefined;
            Shoot.forEach(tree, children, e => {
                if (filter(e)) {
                    ret = e;
                    return false;
                }
            });
            return ret;
        }
    }


    /**
     * 取出满足条件的所有元素
     *
     * @param tree {[TreeNode]}         树
     * @param children {String}         子级列表字段名
     * @param filter {function}         返回 true 的时候，取出该元素
     * @return {[TreeNode]}             至少是一个空的数组
     */
    static fetchArray(tree, children, filter) {
        if (Layers.isNotEmpty(tree)) {
            let ret = [];
            Shoot.forEach(tree, children, e => {
                if (filter(e)) {
                    ret.push(e);
                }
            });
            return ret;
        }
    }

    /**
     * 根据 id 查找特定的节点
     *
     * @param tree {[TreeNode]}         树
     * @param opts {any}                包含字段名配置
     * @param id {String|Number}        ID值
     * @return {TreeNode}               至少是一个空的数组
     */
    static getNodeById(tree, opts, id) {
        let id_ = opts.id, children = opts.children;
        return Shoot.fetch(tree, children, e => e[id_] === id);
    };

    /**
     * 根据 id 查找特定的节点
     *
     * @param tree {[TreeNode]}             树
     * @param opts {any}                包含字段名配置
     * @param ids {[String|Number]}         ID值
     * @return {[TreeNode]}
     */
    static getNodeByIds(tree, opts, ids) {
        let id_ = opts.id, children = opts.children;
        return Shoot.fetchArray(tree, children, e => Layers.contain(ids, e.id));
    };

}

export default Shoot;
